﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Common;
using System.Data.Entity.Migrations;
using System.Data.SqlClient;
using System.IO;
using System.Linq;
using System.Net;
using System.Threading;
using System.Windows.Forms;
using DevExpress.Office.Services;
using DevExpress.Office.Utils;
using DevExpress.XtraRichEdit.API.Word;
using TheHeGeoDao;

namespace TheHeGeoManager.Uc
{
    public partial class UcRestoreData : UcBase
    {
        private int intervalCheck = 10000;
        private int intervalSendData = 50;
        private bool isSendData = false;
        static string connectionString =
                  "Data Source=THEHEGEO;" +
                  "Initial Catalog=TheheGeoDb;" +
                  "Persist Security Info=True;" +
                  "User id=sa;" +
                  "Password=123@trewq;";
      private string RequestUrl = "http://thehegeo.vn:81/postdata.aspx?d=";
       //private string RequestUrl = "http://localhost:3670/PostData.aspx?d=";
        public UcRestoreData()
        {
            InitializeComponent(); 
        }
        public  int InsertRawData(string maThietBi, string Raws, string error, string errorCode)
        {
            string commandText = "INSERT INTO[dbo].[SensorRawData]( [MaThietBi],[Raw], [Error],[ErrorCode],[ThoiGianNhan])" +
                              "VALUES(@MaThietBi,@Raw,@Error,@ErrorCode,@ThoiGianNhan)";

            using (SqlConnection connection = new SqlConnection(connectionString))
            {
                SqlCommand command = new SqlCommand(commandText, connection);

                command.Parameters.Add("@MaThietBi", SqlDbType.VarChar);
                command.Parameters["@MaThietBi"].Value = maThietBi;
                command.Parameters.Add("@Raw", SqlDbType.NVarChar);
                command.Parameters["@Raw"].Value = Raws;
                command.Parameters.Add("@Error", SqlDbType.VarChar);
                command.Parameters["@Error"].Value = error;
                command.Parameters.Add("@ErrorCode", SqlDbType.VarChar);
                command.Parameters["@ErrorCode"].Value = errorCode;
                command.Parameters.Add("@ThoiGianNhan", SqlDbType.DateTime);
                command.Parameters["@ThoiGianNhan"].Value = DateTime.Now;

                try
                {
                    connection.Open();
                    Int32 rowsAffected = command.ExecuteNonQuery();
                    return rowsAffected;
                }
                catch (Exception ex)
                {
                    return -1;
                }
            }
        }
        private void btnStart_Click(object sender, EventArgs e)
        {

            intervalCheck = Convert.ToInt32(txtCheckRequest.Text) * 1000;
            intervalSendData = Convert.ToInt32(txtSendData.Text);
            txtNumbSuccessPkg.Text = "";
            if (isSendData == false)
            {
                isSendData = true;
                Thread t = new Thread(SendData);
                t.Start();
            }
            btnStart.Enabled = false;
        }

        public void StartThread()
        {
            if (isSendData == false)
            {
                intervalCheck = Convert.ToInt32(txtCheckRequest.Text) * 1000;
                intervalSendData = Convert.ToInt32(txtSendData.Text);
                isSendData = true;
                Thread t = new Thread(SendData);
                t.Start();
                btnStart.Enabled = false;
            }

        }
        private void btnStop_Click(object sender, EventArgs e)
        {
            if (InvokeRequired)
            {
                isSendData = false;
            }
            else
            {
                isSendData = false;
            }
            
            btnStart.Enabled = true;
        }

        private void WriteLog(string strLog)
        {
            try
            {
                string path = "Log/log.csv";
                if (!File.Exists(path))
                    File.Create(path);
                using (StreamWriter sw = File.AppendText(path))
                {
                    sw.WriteLine(strLog);
                }	
            }
            catch (Exception)
            {

            } 
        }
        private void DeleteContent()
        {
            try
            {
                string path = "Log/log.csv";
                File.Delete(path);
                File.Create(path);
            }
            catch (Exception)
            {

            }
        }
       
        private void SendData()
        {
            try
            {
                List<String> ListSensor = new List<string>();
                int countUpServerSuccess = 0;
                string str = "";
                int countFromData = 0;
                while (isSendData == true)
                {
                    ListSensor = new List<string>();
                    
                    countUpServerSuccess = 0;
                    countFromData = RemoveDuplicateInLine(ListSensor);
                    RemoveDuplicateAllLine(ListSensor);
                    str += "--------------------------------------------------\r\n";
                    str += "Thời gian restore: " + DateTime.Now.ToString("yy-MM-dd hh:mm:ss:ff") + "\r\n";
                    str += "Số gói đọc từ Database: " + countFromData + "\r\n";
                    str += "Số gói sau khi loại bỏ trùng lặp: " + ListSensor.Count + "\r\n";
                    
                    foreach (var sensor in ListSensor)
                    {
                        try
                        {
                            var request = WebRequest.Create(RequestUrl + sensor);
                            var response = request.GetResponse();
                            var rd = response.GetResponseStream();
                            var strd = new StreamReader(rd);
                            var lstr = strd.ReadToEnd();
                            
                            if (lstr == "CMD:GOOD")
                            {
                                countUpServerSuccess++;
                            }
                            else
                            {
                               string mathietbi = sensor.Substring(8, 6);
                               int res = InsertRawData(mathietbi, sensor, "cannot inset database", "");
                                if(res < 1)
                                    WriteLog(mathietbi + "," + sensor + "," + DateTime.Now.ToString("yy-MM-dd hh-mm-ss-ff"));
                                Thread.Sleep(10000);
                            }
                            Thread.Sleep(intervalSendData);
                        }
                        catch (Exception ex)
                        {
                            string mathietbi = sensor.Substring(8, 6);
                            WriteLog(mathietbi + "," + sensor + "," + DateTime.Now.ToString("yy-MM-dd hh-mm-ss-ff"));
                            InsertRawData(mathietbi, sensor, "cannot inset database", "");
                            Thread.Sleep(10000);
                        }
                    }
                    str += "Số gói gửi lên server: " + countUpServerSuccess + "\r\n";
                    if (InvokeRequired)
                    {
                        txtNumbSuccessPkg.Invoke(new Action(() => txtNumbSuccessPkg.Text = str));
                    }
                    else
                    {
                        txtNumbSuccessPkg.Text = str;
                        //txtNumbSuccessPkg.SelectionStart = txtNumbSuccessPkg.Text.Length;
                       // txtNumbSuccessPkg.ScrollToCaret();
                    }
                    ListSensor.Clear();
                    Thread.Sleep(intervalCheck);
                }
            }
            catch (Exception ex)
            {
               // MessageBox.Show(ex.Message);
            }   
        }

        private void ReadLog(List<String> ListSensor)
        {
            try
            {
                string path = "Log/log.csv";
                using (StreamReader sr = File.OpenText(path))
                {
                    string s = "";
                    while ((s = sr.ReadLine()) != null)
                    {
                       // Console.WriteLine(s);
                        if (s.Contains(','))
                        {
                            var ls = s.Split(',');
                            if(ls.Count()>1)
                            ListSensor.Add(ls[1]);
                        }
                    }
                }
                if (ListSensor.Count>0)
                    DeleteContent();
            }
               
            catch (Exception)
            {
            }
           
        }
        public void ResetMemoEdit(string str)
        {
            txtNumbSuccessPkg.Text = str;
            txtNumbSuccessPkg.SelectionStart = txtNumbSuccessPkg.Text.Length;
            txtNumbSuccessPkg.ScrollToCaret();
        }
        public int RemoveDuplicateInLine(List<String> ListSensor)
        {
            try
            {
                //ReadLog(ListSensor);
                var RawData = (from r in DaoHelper.Entities.SensorRawDatas
                                where (r.ErrorCode == null || r.ErrorCode == "")
                                select r).ToList();
                if (RawData.Count == 0)
                {
                   return ListSensor.Count;
                }
                var lRawData = RawData.ToList();
                int countFromData = lRawData.Count+ListSensor.Count;
                if (lRawData != null && lRawData.Count > 0)
                {
                    List<String> compare = new List<string>();
                    List<string> NewCompare = new List<string>();
                    foreach (var sensorRawData in lRawData)
                    {
                        var sensor = sensorRawData.Raw;
                        var preFirst = sensor.Substring(0, 20);
                        //string noChange = sensor.Substring(14, 6);
                        string numberSensor = sensor.Substring(20, 2);
                        string numberPackage = sensor.Substring(22, 2);
                        string suffix = sensor.Substring(sensor.Length - 26, 26);

                        int lengthOfOnePackage = 14 + 8 * Convert.ToInt32(numberSensor);
                        int lengthOfAllPackage = lengthOfOnePackage * Convert.ToInt32(numberPackage);

                        string package = sensor.Substring((preFirst.Length + numberPackage.Length + numberSensor.Length), lengthOfAllPackage);

                        int numberPackge = package.Length / lengthOfOnePackage;
                        if (Convert.ToInt32(numberPackage) == 1)
                        {
                            string noAdd = preFirst + numberSensor + numberPackage + package + suffix;
                            ListSensor.Add(noAdd);
                        }
                        else
                        {


                            for (var i = 0; i < numberPackge; i++)
                            {
                                string s = package.Substring((lengthOfOnePackage * i), lengthOfOnePackage);
                                compare.Add(s);
                            }
                            NewCompare = compare.Distinct().ToList();
                            compare.Clear();

                            string compareListAfterJoin = String.Join("", NewCompare.ToArray());
                            string sensorDuplicated = preFirst + numberSensor + GetNumberPackage(NewCompare.Count) + compareListAfterJoin +
                                                      suffix;
                            NewCompare.Clear();
                            ListSensor.Add(sensorDuplicated);
                        }
                        DaoHelper.Entities.SensorRawDatas.Remove(sensorRawData);
                    }
                    DaoHelper.Entities.SaveChanges();
                }
                return countFromData;
            }
            catch (Exception ex)
            {
                //MessageBox.Show(ex.StackTrace);
                WriteLog("error" + "," + "lỗi entities: không đọc được dữ liệu" + "," + DateTime.Now.ToString("yy-MM-dd hh-mm-ss-ff"));
                return 0;
            }
        }
        protected string GetNumberPackage(int numbPackage)
        {
            if (numbPackage < 10)
                return "0" + numbPackage;
            return numbPackage.ToString();

        }
        public void RemoveDuplicateAllLine(List<String> ListSensor)
        {
            List<String> Sensor1 = new List<string>();
            List<String> Sensor2 = new List<string>();
            if (ListSensor.Count == 0) return;
            var ListSensor1 = ListSensor.Distinct().ToList();
            ListSensor.Clear();
            ListSensor.AddRange(ListSensor1);
            if (ListSensor.Count == 1)
            {
                return;
            }
           
            for (int index = 0; index < ListSensor.Count; index++)
            {
                var first = ListSensor[index];
                string mathietbi1 = first.Substring(8, 6);
                string soSensor1 = first.Substring(20, 2);
                for (int j = index + 1; j < ListSensor.Count; j++)
                {
                    var second = ListSensor[j];
                    string mathietbi2 = second.Substring(8, 6);
                    string soSensor2 = second.Substring(20, 2);
                    if (mathietbi1.Equals(mathietbi2) && Convert.ToInt32(soSensor1) == Convert.ToInt32(soSensor2))
                    {
                        var preFirst1 = first.Substring(0, 20);
                        string numberSensor1 = first.Substring(20, 2);
                        int numberPackage1 = Convert.ToInt32(first.Substring(22, 2));

                        int lengthOfOnePackage = 14 + 8 * Convert.ToInt32(numberSensor1);
                        int lengthOfAllPackage1 = lengthOfOnePackage * numberPackage1;

                        string package1 = first.Substring((preFirst1.Length + 4), lengthOfAllPackage1);
                        int numberPackge1 = package1.Length / lengthOfOnePackage;

                        for (var i = 0; i < numberPackge1; i++)
                        {
                            string s = package1.Substring((lengthOfOnePackage * i), lengthOfOnePackage);
                            Sensor1.Add(s);
                        }

                        var preFirst2 = second.Substring(0, 20);
                        string numberSensor2 = second.Substring(20, 2);
                        int numberPackage2 = Convert.ToInt32(second.Substring(22, 2));
                        string suffix2 = second.Substring(second.Length - 26, 26);
                        int lengthOfAllPackage2 = lengthOfOnePackage * numberPackage2;

                        string package2 = second.Substring((preFirst2.Length + 4), lengthOfAllPackage2);

                        for (var i = 0; i < numberPackage2; i++)
                        {
                            string s = package2.Substring((lengthOfOnePackage * i), lengthOfOnePackage);
                            Sensor2.Add(s);
                        }
                        foreach (var check1 in Sensor1.ToList())
                        {
                            foreach (var check2 in Sensor2.ToList())
                            {
                                if (check1.Equals(check2))
                                {
                                    Sensor2.Remove(check2);
                                    numberPackage2--;
                                }
                            }
                        }
                        ListSensor.RemoveAt(j);
                        string compareListAfterJoinList2 = String.Join("", Sensor2.ToArray());
                        if (numberPackage2 > 0)
                        {
                            string sensorDuplicated2 = preFirst2 + numberSensor2 + GetNumberPackage(numberPackage2) + compareListAfterJoinList2 +
                                                suffix2;
                            ListSensor.Insert(j,sensorDuplicated2);
                        }
                        Sensor1.Clear();
                        Sensor2.Clear();
                    }
                }
            }
        }

    }

}
